using System;
using System.ComponentModel;
using System.IO;
using System.Security;

namespace Plugins.Serializer
{
    using System.Runtime.Serialization.Formatters.Binary;
    using Interfaces;
    using Internal;
    using Library;

    [Serializable]
    public class PluginBinaryStreamSerializer<T> : PluginStreamSerializer<T>
    {
        protected override bool Serialize(T obj, Stream output, IPluginTypeFormatter formatter)
        {
            try
            {
                IPluginRuntimeSerializerInternal serializer = PluginRuntimeHelper.GetSerializer(typeof(T), formatter);
                if (serializer != null)
                {
                    BinaryFormatter binaryFormatter = new BinaryFormatter();
                    binaryFormatter.Serialize(output, obj);
                    return true;
                }
            }
            catch (ArgumentNullException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (SecurityException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (AccessViolationException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (ApplicationException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (FormatException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (ArgumentException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (UnauthorizedAccessException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (InvalidOperationException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (Win32Exception ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            return false;
        }

        protected override bool Deserialize(Stream input, IPluginTypeFormatter formatter)
        {
            InitializeRuntimeObject(default(T));
            try
            {
                IPluginRuntimeSerializerInternal serializer = PluginRuntimeHelper.GetSerializer(typeof(T), formatter);
                if (serializer != null)
                {
                    BinaryFormatter binaryFormatter = new BinaryFormatter();
                    InitializeRuntimeObject((T)binaryFormatter.Deserialize(input));
                    return true;
                }
            }
            catch (ArgumentNullException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (SecurityException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (AccessViolationException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (ApplicationException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (FormatException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (ArgumentException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (UnauthorizedAccessException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (InvalidOperationException ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            catch (Win32Exception ex)
            {
                PluginLog.WriteErrorSync(ex);
            }
            return false;
        }
    }
}


